/**
 * 全局错误处理
 */
export function setupErrorHandler(app) {
  // Vue错误处理
  app.config.errorHandler = (err, instance, info) => {
    console.error('Vue Error:', err)
    console.error('Component:', instance)
    console.error('Info:', info)
    
    // 在开发环境显示详细错误
    if (import.meta.env.DEV) {
      console.error('Error Stack:', err.stack)
    }
    
    // 在生产环境可以上报错误到服务器
    if (import.meta.env.PROD) {
      // reportError(err, { component: instance?.$options.name, info })
    }
  }
  
  // 全局警告处理
  app.config.warnHandler = (msg, instance, trace) => {
    if (import.meta.env.DEV) {
      console.warn('Vue Warning:', msg)
      console.warn('Component:', instance)
      console.warn('Trace:', trace)
    }
  }
}

/**
 * 未捕获的错误处理
 */
window.addEventListener('error', (event) => {
  console.error('Global Error:', event.error)
  
  if (import.meta.env.PROD) {
    // reportError(event.error, { 
    //   filename: event.filename,
    //   lineno: event.lineno,
    //   colno: event.colno
    // })
  }
})

/**
 * 未捕获的Promise拒绝处理
 */
window.addEventListener('unhandledrejection', (event) => {
  console.error('Unhandled Promise Rejection:', event.reason)
  
  if (import.meta.env.PROD) {
    // reportError(event.reason)
  }
  
  // 阻止在控制台打印默认错误
  event.preventDefault()
})

/**
 * 上报错误到服务器
 * @param {Error} error - 错误对象
 * @param {Object} context - 错误上下文
 */
export function reportError(error, context = {}) {
  const errorInfo = {
    message: error.message,
    stack: error.stack,
    timestamp: new Date().toISOString(),
    url: window.location.href,
    userAgent: navigator.userAgent,
    ...context
  }
  
  // 这里可以发送到错误监控服务
  // 例如：Sentry、LogRocket等
  console.log('Error Report:', errorInfo)
  
  // 示例：发送到后端
  // fetch('/api/errors', {
  //   method: 'POST',
  //   headers: {
  //     'Content-Type': 'application/json'
  //   },
  //   body: JSON.stringify(errorInfo)
  // }).catch(() => {
  //   // 忽略上报失败的错误
  // })
}

/**
 * 错误边界处理
 * @param {Function} fn - 要执行的函数
 * @param {Function} fallback - 错误时的回调
 */
export function withErrorBoundary(fn, fallback) {
  return async (...args) => {
    try {
      return await fn(...args)
    } catch (error) {
      console.error('Error in function:', error)
      
      if (typeof fallback === 'function') {
        return fallback(error, ...args)
      }
      
      throw error
    }
  }
}

/**
 * 异步操作错误处理
 * @param {Promise} promise - Promise对象
 */
export function handleAsyncError(promise) {
  return promise.catch(error => {
    console.error('Async Error:', error)
    reportError(error)
    throw error
  })
}

/**
 * 网络错误处理
 * @param {Error} error - 网络错误
 */
export function handleNetworkError(error) {
  if (!navigator.onLine) {
    return {
      message: '网络连接已断开，请检查网络设置',
      type: 'network'
    }
  }
  
  if (error.code === 'NETWORK_ERROR') {
    return {
      message: '网络请求失败，请稍后重试',
      type: 'network'
    }
  }
  
  if (error.code === 'TIMEOUT') {
    return {
      message: '请求超时，请稍后重试',
      type: 'timeout'
    }
  }
  
  return {
    message: error.message || '网络请求失败',
    type: 'unknown'
  }
}

/**
 * 表单验证错误处理
 * @param {Object} errors - 验证错误对象
 */
export function handleValidationErrors(errors) {
  const errorMessages = []
  
  Object.keys(errors).forEach(field => {
    const fieldErrors = Array.isArray(errors[field]) ? errors[field] : [errors[field]]
    fieldErrors.forEach(error => {
      errorMessages.push(`${field}: ${error}`)
    })
  })
  
  return errorMessages
}

/**
 * 业务错误处理
 * @param {Error} error - 业务错误
 */
export function handleBusinessError(error) {
  const errorMap = {
    'INVALID_CREDENTIALS': '用户名或密码错误',
    'USER_NOT_FOUND': '用户不存在',
    'EMAIL_ALREADY_EXISTS': '邮箱已被注册',
    'PERMISSION_DENIED': '没有权限执行此操作',
    'RESOURCE_NOT_FOUND': '请求的资源不存在',
    'RATE_LIMIT_EXCEEDED': '请求太频繁，请稍后重试',
    'SERVER_ERROR': '服务器内部错误，请稍后重试'
  }
  
  return errorMap[error.code] || error.message || '操作失败，请稍后重试'
}

/**
 * 创建错误对象
 * @param {string} message - 错误消息
 * @param {string} code - 错误代码
 * @param {Object} data - 额外数据
 */
export function createError(message, code, data = {}) {
  const error = new Error(message)
  error.code = code
  error.data = data
  return error
}

export default {
  setupErrorHandler,
  reportError,
  withErrorBoundary,
  handleAsyncError,
  handleNetworkError,
  handleValidationErrors,
  handleBusinessError,
  createError
} 